package ph.com.gs3.formalistics.dao;

import ph.com.gs3.formalistics.model.dao.FLDatabaseHelper;
import ph.com.gs3.formalistics.model.dao.UserAccountsDAO;
import ph.com.gs3.formalistics.model.dao.UserAccountsDAO.IncompleteUserValuesException;
import ph.com.gs3.formalistics.model.valueobjects.business.User;
import ph.com.gs3.formalistics.utilities.FLLogger;
import ph.com.gs3.formalistics.utilities.FLLogger.LogType;
import android.test.AndroidTestCase;
import android.test.RenamingDelegatingContext;

public class UserAccountsDAOTest extends AndroidTestCase {

	public static final String TAG = UserAccountsDAOTest.class.getSimpleName();

	private FLDatabaseHelper testDatabaseHelper;
	private UserAccountsDAO dao;

	private UserAccountsDAOMock mockStore;

	RenamingDelegatingContext context;

	protected void setUp() throws Exception {
		super.setUp();

		context = new RenamingDelegatingContext(getContext(), "test_");
		testDatabaseHelper = new FLDatabaseHelper(context);

		dao = new UserAccountsDAO(testDatabaseHelper);

		// initialize the mock store
		mockStore = new UserAccountsDAOMock();

	}

	// ============================================================================
	// Valid Results Testing

	public void testRegisterUser() {

		// clear the database
		context.deleteDatabase(testDatabaseHelper.getDatabaseName());

		dao.open();
		User registeredUser;
		try {
			registeredUser = dao.registerOrUpdateUser(mockStore.userErvinne);
			// the generated id should be equal to 1 or greater
			assertTrue(registeredUser.getId() > 0);
		} catch (IncompleteUserValuesException e) {
			fail("Unexpected IncompleteUserValuesException" + e.getMessage());
		} finally {
			dao.close();
		}

	}

	public void testUpdateUser() {

		// clear the database
		context.deleteDatabase(testDatabaseHelper.getDatabaseName());

		User userWithUpdates = mockStore.userErvinne;

		String imageURL = "http://local.com/testimage.jpg";

		userWithUpdates.setImageURL(imageURL);

		dao.open();
		try {
			dao.registerOrUpdateUser(mockStore.userErvinne);
			dao.registerOrUpdateUser(userWithUpdates);

			int webId = mockStore.userErvinne.getWebId();
			String server = mockStore.userErvinne.getAccountServer();

			User updatedUser = dao.getUserWithWebIdAndServer(webId, server);
			assertEquals(imageURL, updatedUser.getImageURL());
		} catch (IncompleteUserValuesException e) {
			fail("Unexpected IncompleteUserValuesException" + e.getMessage());
		} finally {
			dao.close();
		}

	}

	public void testRegisterTwoUsers() {

		// clear the database
		context.deleteDatabase(testDatabaseHelper.getDatabaseName());

		dao.open();

		try {
			User registeredErvinne = dao.registerOrUpdateUser(mockStore.userErvinne);
			User registeredDoris = dao.registerOrUpdateUser(mockStore.userDoris);

			assertEquals(1, registeredErvinne.getId());
			assertEquals(2, registeredDoris.getId());

		} catch (IncompleteUserValuesException e) {
			FLLogger.log(TAG, LogType.ERROR, "Unexepected IncompleteUserValuesException, message: "
			        + e.getMessage());
		} finally {
			dao.close();
		}

	}

	// ============================================================================
	// Error Testing

	public void testInvalidServerRegistration() {

		dao.open();

		User invalidUser = mockStore.userErvinne;

		invalidUser.setAccountServer(null);

		try {
			dao.registerOrUpdateUser(invalidUser);
			fail("The user was registered even if he was invalid");
		} catch (IncompleteUserValuesException e) {
			FLLogger.log(TAG, LogType.MESSAGE,
			        "Correct exception thrown, message: " + e.getMessage());
		}

		invalidUser.setAccountServer("");

		try {
			dao.registerOrUpdateUser(invalidUser);
			fail("The user was registered even if he was invalid");
		} catch (IncompleteUserValuesException e) {
			FLLogger.log(TAG, LogType.MESSAGE,
			        "Correct exception thrown, message: " + e.getMessage());
		} finally {
			dao.close();
		}

	}

	public void testInvalidWebIdRegistration() {

		dao.open();

		User invalidUser = mockStore.userErvinne;

		invalidUser.setWebId(0);

		try {
			dao.registerOrUpdateUser(invalidUser);
			fail("The user was registered even if he was invalid");
		} catch (IncompleteUserValuesException e) {
			FLLogger.log(TAG, LogType.MESSAGE,
			        "Correct exception thrown, message: " + e.getMessage());
		}

		invalidUser.setWebId(-1);

		try {
			dao.registerOrUpdateUser(invalidUser);
			fail("The user was registered even if he was invalid");
		} catch (IncompleteUserValuesException e) {
			FLLogger.log(TAG, LogType.MESSAGE,
			        "Correct exception thrown, message: " + e.getMessage());
		} finally {
			dao.close();
		}

	}

}
